package jsr292.java.lang.invoke;

import jsr292.weaver.Capabilities;
import jsr292.weaver.Debug;
import jsr292.weaver.opt.OptimizerContext;
import jsr292.weaver.opt.OptimizerSnippets;
import jsr292.weaver.opt.OptimizerVarAllocator;

class MHConstant extends MethodHandle {
    private final Object value;
    
    public MHConstant(MethodType methodType, Object value) {
	super(methodType);
	this.value = value;
    }

    @Override
    public Object $invoke$() throws Throwable {
	return value;
    }

    @Override
    public boolean isWeavable(Class<?> classBeingRedefined) {
        if (!Capabilities.canDefine()) {
            if (Debug.DEBUG) System.err.println("constant requires define capability");
            return false;
        }
        if (OptimizerSnippets.getBindType(classBeingRedefined, methodType.returnType, value) == null) {
            if (Debug.DEBUG) System.err.println("constant " + value + " can not be bound");
            return false;
        }
        return true;
    }
    @Override
    public void weave(OptimizerContext context, OptimizerVarAllocator allocator) {
        if (Debug.DEBUG) {
            Debug.checkAllocator(allocator, this);
        }
        
        Class<?> declaredType = methodType.returnType;
        OptimizerSnippets.constant(context, value, declaredType,
                OptimizerSnippets.getBindType(context.getClassBeingRedefined(), declaredType, value));
    }
}
